/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
 * Performance Profiler for Vulkan API Instrumentation
 */

#ifndef PERFORMANCE_PROFILER_HPP
#define PERFORMANCE_PROFILER_HPP

#include <chrono>
#include <string>
#include <unordered_map>
#include <vector>
#include <mutex>
#include <fstream>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <Singleton.hpp>
#include <log.hpp>  // OpenHarmony日志系统

/**
 * 性能分析器 - 用于测量 Vulkan API 调用耗时
 * 支持跨平台对比(OpenHarmony vs Android)
 */
class PerformanceProfiler : public OHTestApp::Singleton<PerformanceProfiler> {
public:
    // API 调用记录
    struct ApiCallRecord {
        std::string apiName;
        std::chrono::high_resolution_clock::time_point startTime;
        std::chrono::high_resolution_clock::time_point endTime;
        double durationMicroseconds;
        uint64_t frameIndex;
        
        ApiCallRecord() : durationMicroseconds(0.0), frameIndex(0) {}
    };

    // API 统计信息
    struct ApiStats {
        std::string apiName;
        uint64_t callCount;
        double totalTimeMicroseconds;
        double minTimeMicroseconds;
        double maxTimeMicroseconds;
        double avgTimeMicroseconds;
        
        ApiStats() : callCount(0), totalTimeMicroseconds(0.0), 
                    minTimeMicroseconds(std::numeric_limits<double>::max()),
                    maxTimeMicroseconds(0.0), avgTimeMicroseconds(0.0) {}
    };

    PerformanceProfiler() : m_enabled(false), m_currentFrame(0) {}

    ~PerformanceProfiler() {
        if (m_enabled) {
            ExportToFile();
        }
    }

    // 启用/禁用性能分析
    void Enable(bool enable = true) {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_enabled = enable;
        if (enable) {
            m_records.clear();
            m_stats.clear();
            m_currentFrame = 0;
        }
    }

    bool IsEnabled() const { return m_enabled; }

    // 开始测量 API 调用
    void BeginApiCall(const std::string& apiName) {
        if (!m_enabled) return;
        
        std::lock_guard<std::mutex> lock(m_mutex);
        ApiCallRecord record;
        record.apiName = apiName;
        record.startTime = std::chrono::high_resolution_clock::now();
        record.frameIndex = m_currentFrame;
        
        m_activeRecords[apiName] = record;
    }

    // 结束测量 API 调用
    void EndApiCall(const std::string& apiName) {
        if (!m_enabled) return;
        
        std::lock_guard<std::mutex> lock(m_mutex);
        auto it = m_activeRecords.find(apiName);
        if (it == m_activeRecords.end()) return;
        
        auto& record = it->second;
        record.endTime = std::chrono::high_resolution_clock::now();
        
        auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
            record.endTime - record.startTime);
        record.durationMicroseconds = duration.count() / 1000.0;
        
        // 记录到历史
        m_records.push_back(record);
        
        // 更新统计
        UpdateStats(record);
        
        m_activeRecords.erase(it);
    }

    // 帧标记
    void NextFrame() {
        if (!m_enabled) return;
        std::lock_guard<std::mutex> lock(m_mutex);
        m_currentFrame++;
    }

    // 获取统计信息
    std::vector<ApiStats> GetStats() const {
        std::lock_guard<std::mutex> lock(m_mutex);
        std::vector<ApiStats> result;
        result.reserve(m_stats.size());
        for (const auto& pair : m_stats) {
            result.push_back(pair.second);
        }
        return result;
    }

    // 导出到文件
    void ExportToFile(const std::string& filename = "/data/storage/el2/base/cache/profiling_summary.csv") {
        // 立即输出日志,确认函数被调用
        GOLOGI("[PerformanceProfiler] ===== EXPORT FUNCTION ENTERED =====");
        GOLOGI("[PerformanceProfiler] ExportToFile called, filename: %s", filename.c_str());
        GOLOGI("[PerformanceProfiler] Stats count: %zu", m_stats.size());
        GOLOGI("[PerformanceProfiler] Enabled state: %d", m_enabled ? 1 : 0);
        
        // 确保目录存在
        if (!EnsureDirectoryExists(filename)) {
            GOLOGE("[PerformanceProfiler] Failed to create directory for file: %s", filename.c_str());
            return;
        }
        
        std::lock_guard<std::mutex> lock(m_mutex);
        
        std::ofstream file(filename, std::ios::out | std::ios::trunc);
        if (!file.is_open()) {
            GOLOGE("[PerformanceProfiler] ERROR: Failed to open file: %s", filename.c_str());
            GOLOGE("[PerformanceProfiler] Please check: 1) Directory exists 2) Write permissions 3) Disk space");
            GOLOGE("[PerformanceProfiler] errno: %d, error: %s", errno, strerror(errno));
            return;
        }
        
        GOLOGI("[PerformanceProfiler] File opened successfully");

        // CSV 头部
        file << "API Name,Call Count,Total Time(μs),Min Time(μs),Max Time(μs),Avg Time(μs)\n";
        
        // 写入统计数据
        for (const auto& pair : m_stats) {
            const auto& stats = pair.second;
            file << stats.apiName << ","
                 << stats.callCount << ","
                 << stats.totalTimeMicroseconds << ","
                 << stats.minTimeMicroseconds << ","
                 << stats.maxTimeMicroseconds << ","
                 << stats.avgTimeMicroseconds << "\n";
        }
        
        file.close();
        
        // 设置文件权限为所有人可读 (0644 = rw-r--r--)
        chmod(filename.c_str(), 0644);
        GOLOGI("[PerformanceProfiler] File permissions set to 0644");
        GOLOGI("[PerformanceProfiler] Summary CSV file saved to: %s", filename.c_str());
        GOLOGI("[PerformanceProfiler] Summary CSV export completed successfully");
    }

    // 导出详细记录
    void ExportDetailedRecords(const std::string& filename = "/data/storage/el2/base/cache/profiling_detailed.csv") {
        GOLOGI("[PerformanceProfiler] ===== DETAILED EXPORT FUNCTION ENTERED =====");
        GOLOGI("[PerformanceProfiler] ExportDetailedRecords called, filename: %s", filename.c_str());
        GOLOGI("[PerformanceProfiler] Records count: %zu", m_records.size());
        
        // 确保目录存在
        if (!EnsureDirectoryExists(filename)) {
            GOLOGE("[PerformanceProfiler] Failed to create directory for detailed file: %s", filename.c_str());
            return;
        }
        
        std::lock_guard<std::mutex> lock(m_mutex);
        
        std::ofstream file(filename, std::ios::out | std::ios::trunc);
        if (!file.is_open()) {
            GOLOGE("[PerformanceProfiler] ERROR: Failed to open detailed file: %s", filename.c_str());
            GOLOGE("[PerformanceProfiler] errno: %d, error: %s", errno, strerror(errno));
            return;
        }
        
        GOLOGI("[PerformanceProfiler] Detailed file opened successfully");

        // CSV 头部
        file << "Frame,API Name,Duration(μs)\n";
        
        // 写入详细记录
        for (const auto& record : m_records) {
            file << record.frameIndex << ","
                 << record.apiName << ","
                 << record.durationMicroseconds << "\n";
        }
        
        file.close();
        
        // 设置文件权限为所有人可读 (0644 = rw-r--r--)
        chmod(filename.c_str(), 0644);
        GOLOGI("[PerformanceProfiler] Detailed file permissions set to 0644");
        GOLOGI("[PerformanceProfiler] Detailed CSV file saved to: %s", filename.c_str());
        GOLOGI("[PerformanceProfiler] Detailed CSV export completed successfully");
    }

    // 通过日志导出CSV数据 (用于从设备提取数据)
    void ExportViaLogs() {
        std::lock_guard<std::mutex> lock(m_mutex);
        
        GOLOGI("[PROFILER_CSV_EXPORT_START]");
        GOLOGI("[PROFILER_SUMMARY_HEADER] API Name,Call Count,Total Time(μs),Min Time(μs),Max Time(μs),Avg Time(μs)");
        
        // 导出统计数据
        for (const auto& pair : m_stats) {
            const auto& stats = pair.second;
            GOLOGI("[PROFILER_SUMMARY_DATA] %s,%llu,%.3f,%.3f,%.3f,%.3f",
                   stats.apiName.c_str(),
                   stats.callCount,
                   stats.totalTimeMicroseconds,
                   stats.minTimeMicroseconds,
                   stats.maxTimeMicroseconds,
                   stats.avgTimeMicroseconds);
        }
        
        GOLOGI("[PROFILER_DETAILED_HEADER] Frame,API Name,Duration(μs)");
        
        // 分批导出详细记录 (每批100条,避免日志过长)
        const size_t BATCH_SIZE = 100;
        size_t totalRecords = m_records.size();
        GOLOGI("[PROFILER_DETAILED_INFO] Total records: %zu, will export in batches of %zu", totalRecords, BATCH_SIZE);
        
        for (size_t i = 0; i < m_records.size(); i += BATCH_SIZE) {
            size_t batchEnd = std::min(i + BATCH_SIZE, m_records.size());
            GOLOGI("[PROFILER_DETAILED_BATCH] Batch %zu-%zu of %zu", i, batchEnd - 1, totalRecords);
            
            for (size_t j = i; j < batchEnd; j++) {
                const auto& record = m_records[j];
                GOLOGI("[PROFILER_DETAILED_DATA] %llu,%s,%.3f",
                       record.frameIndex,
                       record.apiName.c_str(),
                       record.durationMicroseconds);
            }
        }
        
        GOLOGI("[PROFILER_CSV_EXPORT_END]");
        GOLOGI("[PerformanceProfiler] Log-based CSV export completed. Total: %zu summary stats, %zu detailed records", 
               m_stats.size(), m_records.size());
    }

    // 打印统计摘要
    void PrintSummary() const;

private:
    // 确保目录存在的辅助函数
    bool EnsureDirectoryExists(const std::string& filepath) {
        // 提取目录路径
        size_t lastSlash = filepath.find_last_of('/');
        if (lastSlash == std::string::npos) {
            return true; // 没有目录,使用当前目录
        }
        
        std::string dirPath = filepath.substr(0, lastSlash);
        GOLOGI("[PerformanceProfiler] Ensuring directory exists: %s", dirPath.c_str());
        
        // 递归创建所有父目录
        std::string currentPath;
        size_t pos = 0;
        while (pos < dirPath.length()) {
            size_t nextSlash = dirPath.find('/', pos + 1);
            if (nextSlash == std::string::npos) {
                currentPath = dirPath;
            } else {
                currentPath = dirPath.substr(0, nextSlash);
            }
            
            // 检查目录是否存在
            struct stat st;
            if (stat(currentPath.c_str(), &st) != 0) {
                // 目录不存在,创建它
                GOLOGI("[PerformanceProfiler] Creating directory: %s", currentPath.c_str());
                if (mkdir(currentPath.c_str(), 0755) != 0 && errno != EEXIST) {
                    GOLOGE("[PerformanceProfiler] Failed to create directory %s: errno=%d, %s", 
                           currentPath.c_str(), errno, strerror(errno));
                    return false;
                }
            }
            
            if (nextSlash == std::string::npos) break;
            pos = nextSlash;
        }
        
        GOLOGI("[PerformanceProfiler] Directory created successfully: %s", dirPath.c_str());
        return true;
    }

    void UpdateStats(const ApiCallRecord& record) {
        auto& stats = m_stats[record.apiName];
        
        if (stats.callCount == 0) {
            stats.apiName = record.apiName;
        }
        
        stats.callCount++;
        stats.totalTimeMicroseconds += record.durationMicroseconds;
        stats.minTimeMicroseconds = std::min(stats.minTimeMicroseconds, record.durationMicroseconds);
        stats.maxTimeMicroseconds = std::max(stats.maxTimeMicroseconds, record.durationMicroseconds);
        stats.avgTimeMicroseconds = stats.totalTimeMicroseconds / stats.callCount;
    }

    bool m_enabled;
    uint64_t m_currentFrame;
    
    mutable std::mutex m_mutex;
    std::vector<ApiCallRecord> m_records;
    std::unordered_map<std::string, ApiStats> m_stats;
    std::unordered_map<std::string, ApiCallRecord> m_activeRecords;
};

// RAII 风格的 API 调用测量器
class ScopedApiProfiler {
public:
    explicit ScopedApiProfiler(const std::string& apiName) : m_apiName(apiName) {
        PerformanceProfiler::Instance().BeginApiCall(m_apiName);
    }
    
    ~ScopedApiProfiler() {
        PerformanceProfiler::Instance().EndApiCall(m_apiName);
    }
    
private:
    std::string m_apiName;
};

// 便捷宏定义
#define PROFILE_API_CALL(apiName) ScopedApiProfiler _profiler_##__LINE__(apiName)
#define PROFILE_VULKAN_API(vkFunc) ScopedApiProfiler _profiler_##__LINE__(#vkFunc)

#endif // PERFORMANCE_PROFILER_HPP
